home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
demos
/
GL
/
newton
/
newton.h
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
10KB
|
424 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* Yossi Friedman, July 1988
*/
#ifdef MAIN
# define extern /* nothing */
# define INIT(val) = val
#else /* MAIN */
# define INIT(val) /* nothing */
#endif /* MAIN */
/*
* set the right flags depending on the current graphics board
*/
#ifdef CLOVER1
# undef HAS_CZCLEAR
# undef HAS_BLENDING
# undef MP
#endif /* CLOVER1 */
#ifdef ECLIPSE
# define HAS_CZCLEAR
# undef HAS_BLENDING
# undef MP
#endif /* ECLIPSE */
#ifdef CLOVER1G
# define HAS_CZCLEAR
# define HAS_BLENDING
# undef MP
#endif /* CLOVER1G */
#ifdef CLOVER2
# define HAS_CZCLEAR
# define HAS_BLENDING
# define MP
#endif /* CLOVER2 */
/*
* Multiprocessor stuff
*/
#ifdef MP
extern int nproc; /* number of CPUs */
extern void slave(void *);
/* functions that slaves can perform: */
# define SLAVE_IDLE 0
# define SLAVE_DIE 1
# define DO_CLEAR 2
# define DO_ACCEL 3
# define DO_BOUNDS 4
# define DO_VEL_DAMP_POS 5
# define DO_ROTATE_MODEL 6
# define DO_ROTATE_PHYSICS 7
# define DRAW_FLAT_SURFS_1 8
# define DRAW_SMOOTH_SURFS_1 9
# define DRAW_SMOOTH_SURFS_2 10
# define DRAW_SMOOTH_SURFS_3 11
# define SLAVE_FUNC(f) \
do { \
int i; \
\
for (i = 0; i < nproc; i++) \
slave_func[i] = f; \
} while (0)
# define WAIT_FOR_SLAVE() \
do { \
int waiting; \
int i; \
\
for (waiting = 1; waiting;) { \
waiting = 0; \
for (i = 1; i < nproc; i++) \
if (slave_func[i] != SLAVE_IDLE) { \
waiting = 1; \
break; \
} \
} \
} while (0);
# define MP_ARRAY [MAX_NPROC]
# define CPU_PARAM , cpu
# define MASTER_PARAM , 0
# define CPU_PARAM_TYPE int cpu
# define CPU [cpu]
# define MASTER [0]
# define TOTAL [nproc-1]
extern volatile int slave_func MP_ARRAY;
extern int slave_pid MP_ARRAY;
/*
* debugging -- DO NOT start the slaves in the main program. Instead,
* redefine WAIT_FOR_SLAVE as:
*
* # define WAIT_FOR_SLAVE() \
* do { \
* int i; \
* for (i = 1; i < nproc; i++) \
* slave(); \
* \
* slave_func[0] = 1; \
* for (i = 1; i < nproc; i++) \
* slave_func[0] &&= (slave_func[i] == SLAVE_IDLE); \
* if (slave_func[0] == 0) \
* fprintf(stderr, "Slave(s) don't signal!\007\n"); \
* } while (0)
*
* Also, remove the infinite loop from the slave routine.
*/
#else /* MP */
# define SLAVE_FUNC(f) do /* nothing */ ; while (0)
# define MP_ARRAY /* nothing */
# define SLAVE_IDLE /* nothing */
# define WAIT_FOR_SLAVE() do /* nothing */ ; while (0)
# define CPU_PARAM /* nothing */
# define MASTER_PARAM /* nothing */
# define CPU_PARAM_TYPE /* nothing */
# define CPU /* nothing */
# define MASTER /* nothing */
# define TOTAL /* nothing */
#endif /* MP */
/*
* indices into a coordinate vector
*/
#define X 0
#define Y 1
#define Z 2
#define W 3
/*
* useful vector macros. they are enclosed in this ridiculous null loop in
* order the make each a pseudo-statement.
*
* NOTE: the operands are nor parenthesized, so the macros should
* be invoked with care (priority of operators).
*/
#define vec_op(v, v1, op, v2) \
/* v = v1 op v2 */ \
do { \
v[X] = v1[X] op v2[X]; \
v[Y] = v1[Y] op v2[Y]; \
v[Z] = v1[Z] op v2[Z]; \
} while (0)
#define cross(v, v1, v2) \
/* v = v1 x v2 */ \
do { \
v[X] = v1[Y]*v2[Z] - v1[Z]*v2[Y] ; \
v[Y] = -(v1[X]*v2[Z] - v1[Z]*v2[X]); \
v[Z] = v1[X]*v2[Y] - v1[Y]*v2[X] ; \
} while (0)
#define dot(v1, v2) (v1[X]*v2[X] + v1[Y]*v2[Y] + v1[Z]*v2[Z])
#define apply(b, a, M) \
/* b = a M */ \
do { \
b[X] = a[X]*M[X][X] + a[Y]*M[Y][X] + a[Z]*M[Z][X] + M[W][X]; \
b[Y] = a[X]*M[X][Y] + a[Y]*M[Y][Y] + a[Z]*M[Z][Y] + M[W][Y]; \
b[Z] = a[X]*M[X][Z] + a[Y]*M[Y][Z] + a[Z]*M[Z][Z] + M[W][Z]; \
} while (0)
#define normalize(v) \
/* v = v / |v| */ \
do { \
\
float leni = 1. / sqrt(v[X]*v[X] + v[Y]*v[Y] + v[Z]*v[Z]); \
\
v[X] *= leni; \
v[Y] *= leni; \
v[Z] *= leni; \
} while (0)
/*
* models catalog file
*/
extern char *model_catalog INIT(DEFAULT_MODEL_CATALOG);
#ifdef CONFIG_FILE
/*
* configuration file
*/
extern char *model_config INIT(DEFAULT_MODEL_CONFIG);
#endif /* CONFIG_FILE */
/*
* the list of models
*/
extern char *model_names[MAX_MODELS], **end_model_names;
extern int model_index; /* index of current model in the name list */
/*
* the physical and geometric elements of the system
*/
typedef struct {
/* physics stuff */
float acc MP_ARRAY [3];
float vel[3];
/* shared stuff between physics and draw */
float pos[3];
/* draw stuff */
float norm MP_ARRAY [3];
} Atom;
typedef struct {
float r0;
float k;
Atom *from;
Atom *to;
} Spring;
typedef struct {
int n;
Atom **vert;
float *norm; /* array of normals, size 4*n. 4 rather than 3 so it
would be fast to go from one normal to the next */
} Surf;
extern Atom model_atoms[MAX_ATOMS], *end_model_atoms MP_ARRAY;
extern Spring model_springs[MAX_SPRING], *end_model_springs MP_ARRAY;
extern Surf model_surfs[MAX_SURF], *end_model_surfs MP_ARRAY;
extern float max_k; /* current maximal model spring constant */
#define MODEL_MATERIAL_INDEX 1
extern float model_material[MAX_LIGHTING_SIZE];
extern int model_material_size;
extern float default_model_material[MAX_LIGHTING_SIZE]
INIT({ DEFAULT_MODEL_MATERIAL });
extern int default_model_material_size
INIT(DEFAULT_MODEL_MATERIAL_SIZE);
/*
* room walls structure
*/
extern struct wall {
/* draw stuff */
float real_v[4][3]; /* real vertices of the wall */
float real_norm[3];
float surf_v[4][3]; /* vertices of the wall surface */
float surf_e[4][3]; /* edges of the wall surface */
float surf_norm[5][3]; /* normals for dented walls */
float shadow[4][4]; /* shadow transformation matrix */
int axis; /* which axis does the wall lie on */
float sign; /* on which side of that axis? +/- 1. */
/* shared stuff between physics and draw -- penetrations into walls */
int penetrated;
float depth;
Atom *atom;
} wall[6];
#define WALL_TOP 0
#define WALL_BOTTOM 1
#define WALL_RIGHT 2
#define WALL_LEFT 3
#define WALL_FRONT 4
#define WALL_BACK 5
/*
* draw functions
*/
extern void draw_smooth_surfs(),
draw_flat_surfs(),
draw_springs(),
(*draw_model)();
extern void draw_lighted_wall(int),
draw_pinball_wall(int),
draw_plain_wall(int),
(*draw_wall)(int) INIT(DRAW_WALL_DEFAULT);
/*
* display state vars
*/
/* display mode -- color map or RGB */
#define RGB 1
#define COLOR_MAP 0
extern int mode INIT(DEFAULT_MODE);
/* should we draw shadows in lighted wall mode? */
extern int shadows_too INIT(SHADOWS_TOO_DEFAULT);
/* should the springs be drawn as well as the surfaces? */
extern int springs_too INIT(SPRINGS_TOO_DEFAULT);
/* should we draw a translucent model? */
extern int alpha_blended INIT(ALPHA_BLENDED_DEFAULT);
/*
* sliders stuff -- common to physics and play:initialize_sliders.
* Physics sets the title, low, hi, dflt, and fun, as well as end_sliders.
* In initialize_sliders, the sid gets set.
*/
struct slider {
char *title;
float lo, hi, dflt;
void (*fun)(float);
int sid;
};
extern struct slider sliders[100], *end_sliders;
/*
* It transpires that because of the user interface, my transformation
* mechanism has to be somewhat different from the one supported by GL.
* I have to separate M (modeling transformations), V (viewing
* trans.) and P (projection trans.). P has to be separated from the
* others because of the lighting model. V and M have to be separated
* because of the rotation of the COORDINATE SYSTEM (rather than the
* objects themselves) -- this forces post-multiplication of M.
* Hence, I use `mmode(MVIEWING)' to keep P separated from the others,
* I keep a constant V at the top of the stack, and I keep M and M-inverse
* soft in my program.
*
* The routine `rotate_graphics' in file draw.c actually changes M
* and M-inverse. The routines `rotate_model' (models.c) and
* `rotate_physics' (physics.c) use those matrices. The reason why they
* need to use them is because rotations happen around a fixed axis in
* the viewing coordinate system, and the coordinates of the model and
* gravity vector are in the modeling coordinate system, which is attached
* to the room -- so in order to rotate around a viewing axis, the model
* and gravity coordinates have to be transformed into viewing coordinates,
* rotated, and returned to modeling coordinates.
*/
#define IDENT_MATRIX \
{ \
{ 1., 0., 0., 0. }, \
{ 0., 1., 0., 0. }, \
{ 0., 0., 1., 0. }, \
{ 0., 0., 0., 1. } \
}
extern Matrix ident_matrix INIT(IDENT_MATRIX);
extern Matrix M INIT(IDENT_MATRIX);
extern Matrix M_inv INIT(IDENT_MATRIX);
extern Matrix R; /* general purpose */
#undef IDENT_MATRIX
#ifdef MAIN
# undef extern
#endif /* MAIN */
#undef INIT
extern void set_default_k(float);
extern void set_k(float);